﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DemoNHibernate.Domain;
using NHibernate;
using NHibernate.Criterion;

namespace DemoNHibernate.DAO
{
	public interface IRepository<T>
    {
        void Add(T product);
        void Update(T product);
        void Remove(T product);
        T GetById(Guid productId);
    }

	public static class Repository<T>
    {
        public static void Add(T oObj)
        {
			if( oObj == null )
				return;

            using (ISession oSession = NHibernateHelper.OpenSession())
                using (ITransaction oTransaction = oSession.BeginTransaction())
                {
                    oSession.Save(oObj);
                    oTransaction.Commit();
                }
        }

		public static void Add(IList<T> oListObj)
        {
			if( oListObj == null )
				return;

            using (ISession oSession = NHibernateHelper.OpenSession())
                using (ITransaction oTransaction = oSession.BeginTransaction())
                {
					bool bCommit = false;
					foreach( T oObj in oListObj )
					{
						oSession.Save(oObj);
						bCommit = true;
					}
					if( bCommit == true )
						oTransaction.Commit();
                }
        }
 
        public static void Update(T oObj)
        {
			if( oObj == null )
				return;

            using (ISession oSession = NHibernateHelper.OpenSession())
            using (ITransaction oTransaction = oSession.BeginTransaction())
            {
                oSession.Update(oObj);
                oTransaction.Commit();
            }
        }
 
        public static void Remove(T oObj)
        {
			if( oObj == null )
				return;

            using (ISession oSession = NHibernateHelper.OpenSession())
                using (ITransaction oTransaction = oSession.BeginTransaction())
                {
                    oSession.Delete(oObj);
                    oTransaction.Commit();
                }
        }

		public static void Remove(IList<T> oListObj)
        {
			if( oListObj == null )
				return;

            using (ISession oSession = NHibernateHelper.OpenSession())
                using (ITransaction oTransaction = oSession.BeginTransaction())
                {
					bool bCommit = false;
					foreach( T oObj in oListObj )
					{
						oSession.Delete(oObj);
						bCommit = true;
					}
					if( bCommit == true )
						oTransaction.Commit();
                }
        }
 
		public static T GetUnique()
        {
			// HQL 
            using (ISession oSession = NHibernateHelper.OpenSession())
			{
				T product = oSession
                    .CreateCriteria(typeof(T))                    
                    .UniqueResult<T>();
                return product;
			}
        }	

        public static T GetById(Guid IdObj)
        {
			if( IdObj.ToString() == "" )
				return default(T);

			// HQL 
            using (ISession oSession = NHibernateHelper.OpenSession())
                return oSession.Get<T>(IdObj);
        }		

		public static T GetBy(string strNameValue, string strValue)
        {
			if( strNameValue == "" || strValue == "" )
				return default(T);

			// HCQ 
            using (ISession oSession = NHibernateHelper.OpenSession())
            {
                T product = oSession
                    .CreateCriteria(typeof(T))
                    .Add(Restrictions.Eq(strNameValue, strValue))
                    .UniqueResult<T>();
                return product;
            }
        }

        public static IList<T> GetList()
        {
			// HCQ 
            using (ISession oSession = NHibernateHelper.OpenSession())
            {
                var products = oSession
                    .CreateCriteria(typeof(T))                    
                    .List<T>();
                return products;
            }
        }

		public static IList<T> GetListBy(string strNameValue, string strValue)
        {
			if( strNameValue == "" || strValue == "" )
				return new List<T>();

			// HCQ 
            using (ISession oSession = NHibernateHelper.OpenSession())
            {
                var products = oSession
                    .CreateCriteria(typeof(T))
                    .Add(Restrictions.Eq(strNameValue, strValue))
                    .List<T>();
                return products;
            }
        }

		public static Object ApplySQL(string strSQL, bool bIsList)
		{
			using (ISession oSession = NHibernateHelper.OpenSession())
            {
				if( bIsList )
					return oSession.CreateQuery(strSQL).List<T>(); 
				else
					return oSession.CreateQuery(strSQL).UniqueResult<T>(); 
			}
		}		
    }	
}
